package com.cheung.shopkeeper.common.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZInputStream;
import com.jcraft.jzlib.ZOutputStream;

public class ZipUtil {
	
	// 输入数据的最大长度
	private static final int BUFFERSIZE = 1024;
	
	/**
	 * 压缩数据
	 * 
	 * @param object
	 * @return
	 * @throws IOException
	 */
	public static byte[] compress(byte[] object) throws IOException {
		
		byte[] data = null;
		try {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ZOutputStream zOut = new ZOutputStream(out, JZlib.Z_BEST_COMPRESSION);
			DataOutputStream objOut = new DataOutputStream(zOut);
			objOut.write(object);
			objOut.close();
			data = out.toByteArray();
			
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		}
		return data;
		
	}
	
	/**
	 * 解压被压缩的数据
	 * 
	 * @param object
	 * @return
	 * @throws IOException
	 */
	public static byte[] unCompress(byte[] object) throws IOException {
		
		byte[] data = new byte[object.length * 200];
		try {
			ByteArrayInputStream in = new ByteArrayInputStream(object);
			ZInputStream zIn = new ZInputStream(in);
			DataInputStream objIn = new DataInputStream(zIn);
			
			int len = 0;
			int count = 0;
			while ((count = objIn.read(data, len, len + BUFFERSIZE)) != -1) {
				len = len + count;
			}
			byte[] trueData = Arrays.copyOf(data, len);
			objIn.close();
			return trueData;
			
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		}
	}
	
	public static String encoding(byte[] compressed) {
		StringBuffer allContacted = new StringBuffer();
		int tenV;
		for (byte b : compressed) {
			
			tenV = b & 0xff;
			
			if (tenV < 16) {
				
				allContacted.append("0" + Integer.toHexString(tenV));
			} else {
				
				allContacted.append(Integer.toHexString(tenV));
			}
			
		}
		return allContacted.toString();
	}
	
	public static byte[] decoding(String encodingString) {
		int start = 0;
		int end = 2;
		byte aa[] = new byte[encodingString.length() / 2];
		int i = 0;
		while (end <= encodingString.length()) {
			
			String twoChar = encodingString.substring(start, end);
			aa[i++] = Integer.valueOf(twoChar, 16).byteValue();
			start = end;
			end = end + 2;
		}
		return aa;
	}
	
	/**
	 * 注意 不支持中文路径(待修复)
	 * 
	 * @param filePath
	 * @param zipFilePath
	 * @throws IOException
	 */
	public static void createZipFile(String filePath, String zipFilePath) throws IOException {
		FileOutputStream fos = null;
		ZipOutputStream zos = null;
		fos = new FileOutputStream(zipFilePath);
		zos = new ZipOutputStream(fos);
		writeZipFile(new File(filePath), zos, "");
		if (zos != null) {
			zos.close();
		}
		if (fos != null) {
			fos.close();
		}
	}
	
	private static void writeZipFile(File f, ZipOutputStream zos, String hiberarchy)
			throws IOException {
		if (f.exists()) {
			if (f.isDirectory()) {
				hiberarchy += f.getName() + "/";
				File[] fif = f.listFiles();
				for (int i = 0; i < fif.length; i++) {
					writeZipFile(fif[i], zos, hiberarchy);
				}
			} else {
				FileInputStream fis = null;
				fis = new FileInputStream(f);
				ZipEntry ze = new ZipEntry(hiberarchy + f.getName());
				zos.putNextEntry(ze);
				byte[] b = new byte[1024];
				int length = -1;
				while ((length = fis.read(b)) != -1) {
					zos.write(b, 0, length);
					b = new byte[1024];
				}
				if (fis != null)
					fis.close();
			}
		}
	}
	
	public static void main(String[] args) throws Exception {
		
		/**
		 * String filename = "D:/Test.xml"; Reader fileReader = new
		 * InputStreamReader(new FileInputStream(filename), "UTF-8");
		 * BufferedReader br = new BufferedReader(fileReader); StringBuffer
		 * stringBuffer = new StringBuffer(); String nextLine = br.readLine();
		 * while (nextLine != null) { stringBuffer.append(nextLine); nextLine =
		 * br.readLine(); } try { String content = stringBuffer.toString(); //
		 * System.out.println(content); byte[] origin = content.getBytes();
		 * System.out.println("orign length is : " + origin.length); byte[]
		 * compressed = compress(origin); String allContactedString =
		 * encoding(compressed); byte[] aa = decoding(allContactedString);
		 * System.out.println("compressed length is : " + compressed.length);
		 * System.out.println("Encoding compressed length is : " +
		 * allContactedString.length()); byte[] unCompressed = unCompress(aa);
		 * FileOutputStream fos = new FileOutputStream("D:/test.txt"); Writer
		 * out = new OutputStreamWriter(fos, "utf-8"); out.write(new
		 * String(unCompressed)); out.close(); fos.close();
		 * System.out.println("unCompressed length is : " +
		 * unCompressed.length); String newContent = new String(unCompressed); }
		 * catch (Exception e) { e.printStackTrace(); }
		 */
		createZipFile("D:\\wombat.log", "D:\\wombat.zip");
		
	}
	
}
